package com.pdlocation.service;

//单次定位工具类
// SingleLocationRequester.java

import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;

import androidx.annotation.NonNull;

import java.util.concurrent.CountDownLatch;

public class SingleLocationRequester {
    private static final String TAG = "SingleLocation";

    private LocationManager locationManager;
    private LocationListener locationListener;
    private SingleLocationCallback callback;
    private CountDownLatch latch;
    private Handler handler;
    private Location bestLocation;

    public interface SingleLocationCallback {
        void onLocationReceived(Location location);

        void onLocationFailed(String errorMessage);
    }

    //优化
    public SingleLocationRequester(Context context) {
        this.locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
        this.handler = new Handler(Looper.getMainLooper());
    }

    @SuppressWarnings("MissingPermission")
    public void requestLocation(@NonNull SingleLocationCallback callback) {
        this.callback = callback;
        this.latch = new CountDownLatch(1);
        this.bestLocation = null;

        try {
            // 检查GPS和网络定位是否可用
            boolean isGpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
            boolean isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);

            if (!isGpsEnabled && !isNetworkEnabled) {
                callback.onLocationFailed("GPS和网络定位均不可用");
                return;
            }

            // 创建位置监听器
            locationListener = new LocationListener() {
                @Override
                public void onLocationChanged(Location location) {
                    if (isBetterLocation(location, bestLocation)) {
                        bestLocation = location;

                        if (latch.getCount() > 0) {
                            if (bestLocation != null) {
                                callback.onLocationReceived(bestLocation);
                            } else {
                                callback.onLocationFailed("定位超时，无法获取位置");
                            }
                            cleanup();
                            latch.countDown();
                        }

                    }
                }

                @Override
                public void onStatusChanged(String provider, int status, Bundle extras) {
                }

                @Override
                public void onProviderEnabled(String provider) {
                }

                @Override
                public void onProviderDisabled(String provider) {
                }
            };

            // 请求位置更新
            if (isGpsEnabled) {
                locationManager.requestSingleUpdate(LocationManager.GPS_PROVIDER, locationListener, null);
            }

            if (isNetworkEnabled) {
                locationManager.requestSingleUpdate(LocationManager.NETWORK_PROVIDER, locationListener, null);
            }

            // 获取最后已知位置
            Location lastGpsLocation = null;
            Location lastNetworkLocation = null;

            try {
                if (isGpsEnabled) {
                    lastGpsLocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
                }
                if (isNetworkEnabled) {
                    lastNetworkLocation = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                }
            } catch (SecurityException e) {
                Log.e(TAG, "获取最后位置失败", e);
            }

            // 选择最佳最后位置
            if (lastGpsLocation != null && lastNetworkLocation != null) {
                bestLocation = isBetterLocation(lastGpsLocation, lastNetworkLocation) ?
                        lastGpsLocation : lastNetworkLocation;
            } else if (lastGpsLocation != null) {
                bestLocation = lastGpsLocation;
            } else if (lastNetworkLocation != null) {
                bestLocation = lastNetworkLocation;
            }
        } catch (Exception e) {
            Log.e(TAG, "请求位置失败", e);
            callback.onLocationFailed("定位过程发生错误: " + e.getMessage());
        }
    }

    private void cleanup() {
        if (locationManager != null && locationListener != null) {
            try {
                locationManager.removeUpdates(locationListener);
            } catch (Exception e) {
                Log.e(TAG, "清理位置监听器失败", e);
            }
        }
    }

    // 判断新位置是否优于当前最佳位置
    private boolean isBetterLocation(Location location, Location currentBestLocation) {
        if (currentBestLocation == null) {
            // 没有当前最佳位置，新位置就是最佳
            return true;
        }

        // 检查新位置的时间是否更新
        long timeDelta = location.getTime() - currentBestLocation.getTime();
        boolean isSignificantlyNewer = timeDelta > 60000; // 1分钟
        boolean isSignificantlyOlder = timeDelta < -60000;
        boolean isNewer = timeDelta > 0;

        // 如果新位置明显更旧，则拒绝
        if (isSignificantlyOlder) {
            return false;
        }

        // 如果新位置明显更新，则接受
        if (isSignificantlyNewer) {
            return true;
        }

        // 检查新位置的精度
        int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation.getAccuracy());
        boolean isLessAccurate = accuracyDelta > 0;
        boolean isMoreAccurate = accuracyDelta < 0;
        boolean isSignificantlyLessAccurate = accuracyDelta > 200; // 200米

        // 检查定位来源
        boolean isFromSameProvider = isSameProvider(location.getProvider(),
                currentBestLocation.getProvider());

        // 根据精度和来源决定是否接受新位置
        if (isMoreAccurate) {
            return true;
        } else if (isNewer && !isLessAccurate) {
            return true;
        } else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) {
            return true;
        }
        return false;
    }

    // 判断两个定位来源是否相同
    private boolean isSameProvider(String provider1, String provider2) {
        if (provider1 == null) {
            return provider2 == null;
        }
        return provider1.equals(provider2);
    }
}

